import { Alert, Tabs, TabItem } from '@aws-amplify/ui-react';

import { AppDirectoryAlert } from '@/components/AppDirectoryAlert';

import { Example } from '@/components/Example';
import { Fragment } from '@/components/Fragment';

Amplify UI Geo is powered by
[Geo APIs](https://docs.amplify.aws/lib/geo/getting-started/q/platform/js/) and
[Amazon Location Service](https://aws.amazon.com/location/).

### Quick Start

<Fragment platforms={['react']}>
  {({ platform }) => import('@/components/AppDirectoryAlert')}
</Fragment>

<Alert variation="info" heading="Create React App setup">
There's a known issue for users of Create React App v4 where the default prod `browserslist` configuration causes build errors when building for production. See the [Create React App Troubleshooting Guide](/getting-started/troubleshooting#create-react-app) to configure Create React App for use with the MapView UI component.
</Alert>

> Prerequisites:
>
> 1. Install`@aws-amplify/ui-react-geo`with [npm](https://www.npmjs.com/) or [yarn](https://yarnpkg.com/). ( e.g. `npm install @aws-amplify/ui-react-geo`)
> 2. Create map resources by following the [Amplify Geo documentation](https://docs.amplify.aws/lib/geo/getting-started/q/platform/js/).

## MapView

The `MapView` component adds an interactive map to your application.

`MapView` is fully integrated with the open source library [react-map-gl](https://visgl.github.io/react-map-gl/) v7
while using [maplibre-gl-js](https://maplibre.org/maplibre-gl-js/docs/API/) as the map tile source. `MapView` is
used as a replacement to `react-map-gl`'s [default map](https://visgl.github.io/react-map-gl/docs/api-reference/map)
and supports the same functionality.

You can import the `MapView` component with related styles and use it in your Amplify application without any
additional configuration.

<Fragment platforms={['react']}>
  {({ platform }) => import(`./fragments/map-quick-start.${platform}.mdx`)}
</Fragment>

<Alert role="none" variation="info">
  If the map isn't taking up the entire screen, try resetting your browser's default CSS body margins:
  <Fragment platforms={['react']}>
    {({ platform }) => import(`./fragments/margin-reset.${platform}.mdx`)}
  </Fragment>
</Alert>

### Setting Initial Viewport

The map's initial viewport can be set with the `initialViewState` property:

<Fragment platforms={['react']}>
  {({ platform }) => import(`./fragments/map-initial-viewport.${platform}.mdx`)}
</Fragment>

### Usage with react-map-gl

#### Moving Marker

The `Marker` component from the `react-map-gl` library can have dynamic `latitude` and `longitude` properties to create
a moving marker. The marker's position will reflect changes in `latitude` and `longitude`.

<Fragment platforms={['react']}>
  {({ platform }) => import(`./fragments/marker-moving.${platform}.mdx`)}
</Fragment>

#### Marker with Popup

The `Popup` component from the `react-map-gl` library can be used with a `Marker` to communicate information to a user
when the marker is clicked. The `offset` property can be used to prevent the popup from overlapping the marker.

<Fragment platforms={['react']}>
  {({ platform }) => import(`./fragments/marker-with-popup.${platform}.mdx`)}
</Fragment>

_Note: Ensure `originalEvent.stopPropagation()` is called in the marker click handler. This allows the `showPopup`
state to be handled by the component._

### Animation and Native Map Methods

You may want to access the [native maplibre-gl map object](https://maplibre.org/maplibre-gl-js/docs/API/classes/maplibregl.Map/) from within the component that renders `<MapView>` (to animate a viewport transition with `flyTo`, for example). To accomplish this, you can pass your own ref to `<MapView>` using [React's `useRef` hook](https://legacy.reactjs.org/docs/hooks-reference.html#useref) which will contain the `map` object:

<Fragment platforms={['react']}>
  {({ platform }) => import(`./fragments/map-ref.${platform}.mdx`)}
</Fragment>

If you want access to the `map` object in a child component of `<MapView>`, you can use the [useMap hook from react-map-gl](https://visgl.github.io/react-map-gl/docs/api-reference/use-map) instead:

<Fragment platforms={['react']}>
  {({ platform }) => import(`./fragments/use-map.${platform}.mdx`)}
</Fragment>

## Location Search

`LocationSearch` provides location search powered by [Amazon Location Service](https://aws.amazon.com/location/) for the
`MapView` component, using the viewport as the proximity for generating results. `LocationSearch` is used as a child
component of `MapView` for which it renders visual markers and information based on its location search results.

You can import the `LocationSearch` component with related styles and use it as a child of `MapView` without any
additional configuration.

<Fragment platforms={['react']}>
  {({ platform }) =>
    import(`./fragments/location-search-quick-start.${platform}.mdx`)
  }
</Fragment>

### LocationSearch Position

`LocationSearch` can be provided a `position` property when used with `MapView`. The property is not reactive, meaning the
position is fixed after the component mounts. Valid values are `'top-right'`, `'top-left'`, `'bottom-right'`, and
`'bottom-left'`. Default value is `'top-right'`.

<Fragment platforms={['react']}>
  {({ platform }) =>
    import(`./fragments/location-search-position.${platform}.mdx`)
  }
</Fragment>

### Standalone LocationSearch

`LocationSearch` can also be used as a standalone component without `MapView`. As a standalone component, `LocationSearch`
provides search results based on an initial proximity. When used as a standlone component, the `proximity` property
with provided `latitude` and `longitude` properties is required.

<Fragment platforms={['react']}>
  {({ platform }) =>
    import(`./fragments/location-search-standalone.${platform}.mdx`)
  }
</Fragment>
